package com.tensquare.article.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.tensquare.article.client.NoticeClient;
import com.tensquare.article.dao.ArticleDao;
import com.tensquare.article.pojo.Article;
import com.tensquare.article.pojo.Notice;
import com.tensquare.util.IdWorker;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class ArticleService {

    @Autowired
    private ArticleDao articleDao;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private NoticeClient noticeClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public List<Article> findAll() {
        List<Article> articleList = articleDao.selectList(null);
        return articleList;
    }

    public Article findById(String articleId) {
        Article article = articleDao.selectById(articleId);
        return article;
    }

    public void save(Article article) {
        //todo:通过鉴权方式获得作者id
        String userId = "4";
        article.setUserid(userId);

        //分布式id生成器生成id
        String id = idWorker.nextId() + "";

        article.setId(id);
        //访问量
        article.setVisits(0);
        //评论量
        article.setComment(0);
        //点赞量
        article.setThumbup(0);

        articleDao.insert(article);

        //新增后创建消息通知订阅者
        //获取订阅者信息,
        String authorKey = "article_author_" + userId;
        Set<String> members = redisTemplate.boundSetOps(authorKey).members();
        //给订阅者创建消息通知
        for (String uid : members) {
            //创建消息对象设置相关数据
            Notice notice = new Notice();
            //消息通知
            notice.setReceiverId(uid);
            notice.setOperatorId(userId);
            notice.setAction("publish");
            notice.setTargetType("article");
            notice.setTargetId(id);
            notice.setCreatetime(new Date());
            notice.setType("sys");
            notice.setState("0");

            noticeClient.save(notice);
        }
        //使用rabbitMQ发送消息通知
        rabbitTemplate.convertAndSend("article_subscribe",userId,id);


    }

    public void updateById(Article article) {
        //根据主键修改
        articleDao.updateById(article);

     /*   //根据条件修改
        //创建条件对象
        EntityWrapper<Article> wrapper = new EntityWrapper<>();
        //设置条件
        wrapper.eq("id", article);
        articleDao.update(article, wrapper);*/
    }

    public void deleteById(String articleId) {
        articleDao.deleteById(articleId);
    }

    public Page<Article> findByPage(Map<String, Object> map, Integer page, Integer size) {
        //设置查询条件
        EntityWrapper<Article> wrapper = new EntityWrapper<>();
        for (String key : map.keySet()) {
           /* if (map.get(key) != null) {
                wrapper.eq(key, map.get(key));
            } eq方法等效*/
            wrapper.eq(map.get(key) != null, key, map.get(key));
        }
        //设置分页参数
        Page<Article> articlePage = new Page<>(page, size);
        //执行查询
        List<Article> articleList = articleDao.selectPage(articlePage, wrapper);
        articlePage.setRecords(articleList);
        //返回
        return articlePage;
    }

    /**
     * 订阅方法
     *
     * @param articleId
     * @param userId
     * @return
     */
    public Boolean subscribe(String articleId, String userId) {
        //根据文章id查询文章作者id
        String authorId = articleDao.selectById(articleId).getUserid();


        //使用RabbitMq进行消息的发送
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate.getConnectionFactory());
        DirectExchange exchange = new DirectExchange("article_subscribe");
        rabbitAdmin.declareExchange(exchange);
        Queue queue = new Queue("article_subscribe_"+userId,true);
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(authorId);


        //设置作者和用户之间的订阅关系
        String userKey = "article_subscribe_" + userId;
        String authorKey = "article_author_" + authorId;
        //查看用户订阅关系,是否订阅该作者
        Boolean flag = redisTemplate.boundSetOps(userKey).isMember(authorId);
        if (flag) {
            //如果已经订阅,取消订阅该作者,双向删除
            redisTemplate.boundSetOps(userKey).remove(authorId);
            redisTemplate.boundSetOps(authorKey).remove(userId);
            rabbitAdmin.removeBinding(binding);
            //取消订阅,返回false
            return false;
        } else {
            //如果未订阅,订阅该作者,双向添加
            redisTemplate.boundSetOps(userKey).add(authorId);
            redisTemplate.boundSetOps(authorKey).add(userId);
            rabbitAdmin.declareQueue(queue);
            rabbitAdmin.declareBinding(binding);
            //订阅成功,返回true
            return true;
        }
    }

    /**
     * 文章点赞
     * @param articleId
     */
    public void thumbup(String articleId,String userId) {
        Article article = articleDao.selectById(articleId);
        article.setThumbup(article.getThumbup()+1);
        articleDao.updateById(article);

        //点赞后,发送消息给文章作者(点对点消息)

        //消息通知
      Notice notice = new Notice();
      notice.setReceiverId(article.getUserid());
      notice.setOperatorId(userId);
      notice.setAction("thumbup");
      notice.setTargetType("article");
      notice.setTargetId(articleId);
      notice.setCreatetime(new Date());
      notice.setType("user");
      notice.setState("0");
      noticeClient.save(notice);



        //使用RabbitMq进行消息的发送
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate.getConnectionFactory());
        Queue queue = new Queue("article_thumbup_"+article.getUserid(),true);
        rabbitAdmin.declareQueue(queue);
        rabbitTemplate.convertAndSend("article_thumbup_"+article.getUserid(),article.getTitle());

    }
}
